<template>
  <div id="quillEditor">
    <quill-editor
      ref="myQuillEditor"
      v-model="content"
      :options="editorOption"
      @change="onEditorChange($event)"
    ></quill-editor>
    <div class="limit">
      <span>{{ nowLength }}</span> / {{ overText }}
    </div>
    <!-- 图片上传 -->
    <el-upload
      class="uploadImg"
      style="height:0"
      action="#"
      :accept="imgAccept"
      :before-upload="imgBeforeUpload"
      :show-file-list="false"
      :http-request="uploadOss"
    >
    </el-upload>
    <!-- 视频上传 -->
    <el-upload
      class="uploadVideo"
      style="height:0"
      action="#"
      :accept="videoAccept"
      :before-upload="videoBeforeUpload"
      :show-file-list="false"
      :http-request="uploadOss"
    >
    </el-upload>
  </div>
</template>

<script>
import { quillEditor } from 'vue-quill-editor'
import { getOssKey } from '@utils/countDownload'
export default {
  components: { quillEditor },
  props: {
    contents: {
      type: String,
      default: function() {
        return ''
      }
    },
    imgSize: {
      type: Number,
      default: function() {
        return 10
      }
    },
    imgAccept: {
      type: String,
      default: function() {
        return '.jpg, .jpeg, .png, .gif'
      }
    },
    videoSize: {
      type: Number,
      default: function() {
        return 200
      }
    },
    videoAccept: {
      type: String,
      default: function() {
        return '.mp4'
      }
    },
    overText: {
      type: Number,
      default: function() {
        return 2000
      }
    },
    toolbar: {
      type: Object,
      default: function() {
        return {
          container: [
            ['bold', 'italic', 'underline', 'strike'],
            [{ header: 1 }, { header: 2 }],
            [{ list: 'ordered' }, { list: 'bullet' }],
            [{ color: [] }, { background: [] }],
            [{ align: [] }],
            ['image', 'video']
          ],
          handlers: {
            video: () => {
              this.uploadImgVideo('.uploadVideo input')
              this.uploadType = 'video'
            },
            image: () => {
              this.uploadImgVideo('.uploadImg input')
              this.uploadType = 'image'
            }
          }
        }
      }
    }
  },
  watch: {
    contents: {
      handler(newVal) {
        this.content = newVal
      },
      deep: true,
      immediate: true
    }
  },
  data() {
    return {
      editorOption: {
        modules: {
          toolbar: this.toolbar
        },
        placeholder: '请输入内容'
      },
      content: '',
      nowLength: '', //字数
      editorIndex: 0, //光标位置
      uploadType: ''
    }
  },
  mounted() {
    this.nowLength = this.$refs.myQuillEditor.quill.getLength() - 1
  },
  methods: {
    /* 上传图片或视频获取光标位置 */
    uploadImgVideo(val) {
      const cursor = this.$refs.myQuillEditor.quill.getSelection()
      this.editorIndex = cursor ? cursor.index : 0
      document.querySelector(val).click()
    },
    /* 图片上传之前 */
    imgBeforeUpload(file) {
      const fileSuffix = file.name.substring(file.name.lastIndexOf('.'))
      if (this.imgAccept.indexOf(fileSuffix) === -1) {
        this.$message.warning(`不支持上传${fileSuffix}类型图片`)
        return false
      }
      if (file.size / 1024 / 1024 > this.imgSize) {
        this.$message.error(
          `单张图片不能超过${this.imgSize}M,请检查 “${file.name}” 图片大小`
        )
        return false
      }
    },
    /* 视频上传之前 */
    videoBeforeUpload(file) {
      const fileSuffix = file.name.substring(file.name.lastIndexOf('.'))
      if (this.videoAccept.indexOf(fileSuffix) === -1) {
        this.$message.warning(`不支持上传${fileSuffix}类型视频`)
        return false
      }
      if (file.size / 1024 / 1024 > this.videoSize) {
        this.$message.error(
          `单个视频不能超过${this.videoSize}M,请检查 “${file.name}” 视频大小`
        )
        return false
      }
    },
    /* 计算字数 */
    onEditorChange(e) {
      e.quill.deleteText(this.overText, 1)
      if (this.content === 0) {
        this.nowLength = 0
      } else {
        this.nowLength = e.quill.getLength() - 1
      }
      this.$emit('quillEditorContent', this.content, this.nowLength)
    },
    /* oss临时授权上传 */
    uploadOss(param) {
      let _this = this
      const bucketName =
        process.env.VUE_APP_ENV === 'testENV'
          ? 'dapeng-test-image'
          : 'dapeng-image'
      const date = this.moment(new Date().getTime()).format('YYYY-MM-DD')
      const userId = this.$store.state.user.dapengUserId
      const fileSuffix = param.file.name.substring(
        param.file.name.lastIndexOf('.')
      )
      getOssKey({}, (res) => {
        const client = new OSS({
          // yourRegion填写Bucket所在地域。以华东1（杭州）为例，yourRegion填写为oss-cn-hangzhou。
          region: 'oss-cn-beijing',
          // 从STS服务获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
          accessKeyId: res.accessKeyId,
          accessKeySecret: res.accessKeySecret,
          // 从STS服务获取的安全令牌（SecurityToken）。
          stsToken: res.securityToken,
          // 填写Bucket名称。
          bucket: bucketName
        })
        const uploadUrl = `${date}/${userId}/${new Date().getTime()}_T1BFUkFURQ==${fileSuffix}`
        async function put() {
          try {
            // 填写Object完整路径和本地文件的完整路径。Object完整路径中不能包含Bucket名称。
            // 如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。
            await client.put(uploadUrl, param.file)
            let quill = _this.$refs.myQuillEditor.quill
            const url = `${process.env.VUE_APP_OSS_URL}${uploadUrl}`
            quill.insertEmbed(_this.editorIndex++, _this.uploadType, url)
            quill.setSelection(_this.editorIndex)
          } catch (e) {
            _this.$message.error('上传失败')
          }
        }
        put()
      })
    }
  }
}
</script>

<style lang="less" scoped>
:deep(.ql-container) {
  height: 300px !important;
}
.limit {
  position: relative;
  margin: -35px 20px 0 0;
  text-align: right;
  z-index: 9999;
  span {
    color: #f00;
  }
}
</style>
